package com.xxm.mediacodec

import android.content.Intent
import android.graphics.Canvas
import android.graphics.Rect
import android.media.MediaMetadataRetriever
import android.media.ThumbnailUtils
import android.os.Build
import android.os.Bundle
import android.os.CancellationSignal
import android.provider.MediaStore
import android.provider.MediaStore.Video.Media
import android.util.Log
import android.util.Size
import android.view.SurfaceHolder
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import com.xxm.R
import com.xxm.databinding.ActivityMediaCodecBinding
import java.io.File

/**
 * 播放视频 学习编解码 SurfaceView,MediaCodec,MediaExtractor
 */
class MediaCodecActivity : AppCompatActivity(), SurfaceHolder.Callback {
    private val TAG = "MediaCodecActivity"
    val model by lazy {
        ViewModelProvider(this)[MediaCodecModel::class.java]
    }

    private var path = ""

    private lateinit var binding: ActivityMediaCodecBinding

    private var holder: SurfaceHolder? = null

    private var loadThumbnail = true

    @RequiresApi(Build.VERSION_CODES.Q)
    val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
        it?.let { activityResult ->
            val uri = activityResult.data?.data!!


            contentResolver.query(uri, null, null, null, null)?.apply {
                moveToFirst()

                path = getString(getColumnIndex(Media.DATA) ?: 0) ?: "未选择路径"
                val name = getString(getColumnIndex(Media.DISPLAY_NAME) ?: 0)
                val size = getString(getColumnIndex(Media.SIZE) ?: 0)
                val width = getString(getColumnIndex(Media.WIDTH) ?: 0)
                val height = getString(getColumnIndex(Media.HEIGHT) ?: 0)
                if (width.toInt() != 0 && height.toInt() != 0) {
                    val curHeight = binding.surfaceView.width / (width.toFloat() / height.toFloat())
                    binding.surfaceView.layoutParams.height = curHeight.toInt()
                }
                val msg = "视频路径:${path}\n名称：${name}\n" +
                        "分辨率：${width}*${height},大小:${model.formatFileSize(size.toLong())}"
                loadThumbnail = true
                Log.d(TAG, msg)
                binding.tvHint.text = msg
            }


        }

    }

    @RequiresApi(Build.VERSION_CODES.Q)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding =
            DataBindingUtil.setContentView(this, R.layout.activity_media_codec)
        model.supportCodecType()
        binding.surfaceView.holder.addCallback(this)

        binding.tvStartPlay.setOnClickListener {
            if (path.isEmpty()) {
                binding.tvHint.visibility = View.VISIBLE
            }
            holder?.let {
                model.start(path, holder!!)
            }
        }

        binding.tvStopPlay.setOnClickListener {
            model.stop()
        }

        binding.tvSelectVideo.setOnClickListener {

            launcher.launch(Intent(Intent.ACTION_PICK).apply {
                type = "video/*"
            })

        }


    }

    override fun surfaceCreated(holder: SurfaceHolder) {
        this.holder = holder
        Log.d(TAG, "surface created")
    }

    /**
     * 设置首帧图片后，Surface不清理的话设置MediaCodec会报错，表示Surface已被连接
     * 通过调用下面两个函数，会导致surfaceCreated和surfaceChanged函数回调，创立新的Surface，需要在主线程调用
     *     holder.setFormat(PixelFormat.TRANSPARENT);
     *      holder.setFormat(PixelFormat.OPAQUE);
     * 所以图片的显示时机要根据业务调整
     */
    override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
        Log.d(TAG, "surface changed")
        this.holder = holder
        if (loadThumbnail) {
            loadThumbnail = false
            if (path.isNotEmpty()) {
                var bitmap = MediaMetadataRetriever().apply {
                    setDataSource(path)
                }.frameAtTime
                model.setThumbnail(holder, bitmap!!, width, height)
            }
        }
    }

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        model.stop()
    }
}